package service

import (
    "authserver/constants"
    "authserver/global"
    "authserver/model"
    "authserver/utils"
    "encoding/json"
    "errors"
    "strings"
    "time"
)

type Request struct {
    Model string `json:"model"`
    Input Input `json:"input"`
}

type Input struct {
    Messages []Messages `json:"messages"`
}

type Messages struct {
    Role    string        `json:"role"`
    Content []interface{} `json:"content"`
}

type RespBody struct {
    Output Output `json:"output"`
    Usage Usage `json:"usage"`
}

type Output struct {
    Choices []Choices `json:"choices"`
}

type Choices struct {
    Message RespMessages `json:"message"`
}

type RespMessages struct {
    Role    string        `json:"role"`
    Content []struct{
        Text string `json:"text"`
    } `json:"content"`
}

type Usage struct {
    TotalTokens int `json:"total_tokens"`
    OutputTokens int `json:"output_tokens"`
    InputTokens int `json:"input_tokens"`
}

const postUrl="https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
const ak = "sk-c3769e7e449d4a1bae96d475951cb0a0"


//
// SaveCheckInfo
//  @Description: 提交发票信息
//  @param req
//  @return err
//
func SaveCheckInfo(req model.InvoiceCheckInfo) (err error) {

    // 检查数据库，是否已经核验
    var checkInfo model.InvoiceCheckInfo
    global.GVA_DB.Table(model.InvoiceCheckInfo{}.TableName()).
        Where("invoice_code = ?",req.InvoiceCode).
        Find(&checkInfo)
    if checkInfo.Id==0{
        err=global.GVA_DB.Create(&req).Error
        if err!=nil{
            err = errors.New("提交失败，请联系作者！")
            return
        }

    }else{
        return nil
    }

    return nil
}


//
// InvoiceCheck
//  @Description: 解析发票
//  @param imgUrl
//  @return resp
//  @return err
//
func InvoiceCheck(imgUrl string,username string) (resp model.InvoiceCheckInfo,err error) {
    msgInfo := Messages{
        Role: "user",
        Content: []interface{}{
            map[string]interface{}{
                "image":      imgUrl,
                "min_pixels": 3136,
                "max_pixels": 6422528,
            },
            map[string]string{
                "type": "text",
                "text": `请提取车票图像中的发票号码、开票日期，购买方姓名，纳税人识别号，发票金额。
                      要求准确无误的提取上述关键信息、不要遗漏和捏造虚假信息，模糊或者强光遮挡的单个文字可以用英文问号?代替。
                      返回数据格式以json字符串方式输出，格式为：
                      {'发票号码'：'xxx', '开票日期'：'xxx', '购买方姓名'：'xxx', '购方纳税人识别号'：'xxx', '发票金额'：'xxx'}
                      直接返回json字符串,禁止使用markdown格式输出。`,
            },
        },
    }

    reqBody := Request{
        Model: "qwen-vl-ocr-latest",
        Input: Input{Messages: []Messages{msgInfo}},
    }

    reqBodyBytes, err := json.Marshal(reqBody)
    if err != nil {
        return resp, err
    }

    header:= map[string]string{
        "Authorization":"Bearer "+ak,
        "Content-Type":"application/json",
    }

    var respByte []byte

    respByte,err=utils.PostJSON(postUrl,reqBodyBytes,nil,header)
    if err!=nil{
        global.GVA_LOG.Error(err.Error())
        return
    }
    var respBody RespBody

    global.GVA_LOG.Error(string(respByte))
    err=json.Unmarshal(respByte,&respBody)
    if err!=nil{
        global.GVA_LOG.Error(err.Error())
        return
    }

    choices:=respBody.Output.Choices
    if len(choices)==0{
        err = errors.New("解析失败")
        return
    }

    text := choices[0].Message.Content[0].Text

    text=strings.Replace(text,"```json","",-1)
    text=strings.Replace(text,"```","",-1)

    var invoiceInfo model.InvoiceInfo

    err=json.Unmarshal([]byte(text),&invoiceInfo)
    if err!=nil{
        global.GVA_LOG.Error(err.Error())
        return
    }
    invoiceInfo.TotalToken = respBody.Usage.TotalTokens

    if invoiceInfo.InvoiceCode=="" {
        err = errors.New("未识别到发票信息")
        return
    }

    // 检查数据库，是否已经核验
    var checkInfo model.InvoiceCheckInfo
    global.GVA_DB.Table(model.InvoiceCheckInfo{}.TableName()).
        Where("invoice_code = ?",invoiceInfo.InvoiceCode).
        Find(&checkInfo)

    if checkInfo.Id==0{
        checkInfo.IsChecked = 0
        checkInfo.InvoiceDate = invoiceInfo.InvoiceDate
        checkInfo.InvoiceCode = invoiceInfo.InvoiceCode
        checkInfo.BuyMoney = invoiceInfo.BuyMoney
        checkInfo.BuyerName = invoiceInfo.BuyerName
        checkInfo.TotalToken = invoiceInfo.TotalToken
        checkInfo.CheckUser = username
        checkInfo.CheckTime = time.Now().Format(constants.DayTime)
        //global.GVA_DB.Create(&checkInfo)
    }else{
        checkInfo.IsChecked=1
    }

    return checkInfo,nil
}


